const axios = require('axios');
const fs = require('fs');
const FormData = require('form-data'); // Move require to top level
const APP = require('./APP');
class YoloDetector {
    version = 15;
    callTime = new Map();
    localData = new Map();
    isInit = new Map();
    constructor() {
        if (YoloDetector.instance) {
            return YoloDetector.instance;
        }
        this.url = 'http://192.168.1.8:9528/pt_model_predict';
        this.classFile = `D:\\autoGame\\YoloTrain_V1.0.0.9_Plus\\game5\\detect\\train${this.version}\\weights\\classes.txt`;
        this.classNames = fs.readFileSync(this.classFile, 'utf8').trim().split('\n');
        YoloDetector.instance = this;
    }
    async init() {
        if (this.isInit.size == 0) {
            console.log('yolo初始化');
            await new Promise(resolve => setTimeout(resolve, 3000));
            this.isInit.set(1, true);
            console.log('yolo初始化完成');
        }
    }
    async screen(androidBot) {
        let androidId = await androidBot.getAndroidId();
        let time = Date.now();
        if (this.callTime.has(androidId)) {
            let oldTime = this.callTime.get(androidId);
            if (time - oldTime < 200) {
                console.log('yolov8缓存');
                return this.localData.get(androidId);
            }
        }
        let img = await androidBot.takeScreenshot();

        let data = await this.buffer(img);
        for (let item of data) {
            let info = await androidBot.ocr(item.region[0],item.region[1],item.region[2],item.region[3],0,0,0,1.0);
            if(info){
                item.text = info[0][1][0].toLowerCase();
            }else{
                item.text = '';
            }
            item.click = async () => {
                console.log('点击:',item.className,item.text);
                await APP.clickRegion(androidBot,item.region);
                await APP.sleep(1000);
                console.log('点击完成');
            }
        }
        this.callTime.set(androidId, Date.now());
        this.localData.set(androidId, data);
        return data;
    }
    async buffer(imageBuffer) {
        const formData = new FormData();
        formData.append('file', imageBuffer, 'image.png');
        formData.append('get_class_name', '*');

        // 发起POST请求
        const startTime = Date.now();
        const response = await axios.post(this.url, formData, {
            headers: formData.getHeaders()
        });
        const endTime = Date.now();
        // console.log(`yolo耗时: ${(endTime - startTime) / 1000}秒`);
        const result = response.data;
        // 返回一个对象
        let data = []
        // 遍历检测结果并输出
        for (const box of result.IdentifyData) {
            const [x1, y1, x2, y2, classId, confidence] = box;

            const className = parseInt(classId) < this.classNames.length ?
                this.classNames[parseInt(classId)] :
                classId.toString();

            data.push({ className, confidence, region: [x1, y1, x2, y2] });
        }
        // 根据confidence 从大到小排序
        data = data.sort((a, b) => b.confidence - a.confidence);
        console.log(data);
        return data;
    }
    async path(imagePath = './screenshot.png') {
        // 读取图片文件
        const imageBuffer = fs.readFileSync(imagePath);

        return await this.buffer(imageBuffer);
    }
}

// 创建单例实例
const instance = new YoloDetector();
Object.freeze(instance);

module.exports = instance;
